/* $Id: AppMetaDataDomainObjectManagerImpl.java 
 * Copyright (C) 2011, TRAKHEES
 *  
 * Revision History
 *
 * Date  			Author 		    	Remarks
 * ---------------------------------------------------------------------------------
 *
 */
package ae.pcfc.etks.online.common.domain.manager.provider;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.springframework.transaction.annotation.Transactional;

import ae.pcfc.etks.online.common.ConstantsCommon;
import ae.pcfc.etks.online.common.ConstantsCommon.WFProcessType;
import ae.pcfc.etks.online.common.dao.AppMetaDataDAO;
import ae.pcfc.etks.online.common.domain.AppMetaData;
import ae.pcfc.etks.online.common.domain.ProcStepActions;
import ae.pcfc.etks.online.common.domain.ProcStepsComnts;
import ae.pcfc.etks.online.common.domain.ProcessStep;
import ae.pcfc.etks.online.common.domain.manager.AppMetaDataDomainObjectManager;
import ae.pcfc.etks.online.common.exception.LookupException;
import ae.pcfc.etks.online.common.exception.PersistenceException;
import ae.pcfc.etks.online.common.vo.AppMetaDataDetailVO;
import ae.pcfc.etks.online.common.vo.LabelVO;
import ae.pcfc.etks.online.common.vo.WorkflowRequestSearchCriteriaVO;
import ae.pcfc.etks.online.common.vo.WorkflowRequestVO;

public class AppMetaDataDomainObjectManagerImpl implements AppMetaDataDomainObjectManager {

	private AppMetaDataDAO appMetaDataDAO;

	public void setAppMetaDataDAO(AppMetaDataDAO appMetaDataDAO) {
		this.appMetaDataDAO = appMetaDataDAO;
	}

	public <T> void add(T obj) throws PersistenceException {

		this.appMetaDataDAO.add((AppMetaData) obj);

	}

	public <T> void update(T obj) throws PersistenceException {
		this.appMetaDataDAO.update((AppMetaData) obj);
	}

	public <T> void delete(T obj) throws PersistenceException {
		// TODO Auto-generated method stub

	}

	@SuppressWarnings("unchecked")
	public <T> T findByPrimaryKey(String id) throws LookupException {
		if (id == null)
			return null;
		return (T) appMetaDataDAO.findByPrimaryKey(id);
	}

	public <T> Collection<T> findAll() throws LookupException {
		// TODO Auto-generated method stub
		return null;
	}
	/**
	 * Description:
	 * findByPrimaryKeyProcessAndStepCode:	Method to find the Application requests by Process Code and Step Code
	 * This method acquires the AppMetaData domain objects for the user from the AppMetaDataDAO
	 * @param	userId Long	Unique User ID
	 * @throws	LookupException
	 * @return	AppMetaData - returns AppMetaData
	 */	
	public AppMetaData findByPrimaryKeyProcessAndStepCode(String id, String proccesCode, String processStepCode)
			throws LookupException {

		return this.appMetaDataDAO.findByPrimaryKeyProcessAndStepCode(id, proccesCode, processStepCode);
	}
	/**
	 * Description:
	 * getNextApplicationId:	Method to find the next application id in the sequence
	 * This method acquires the AppMetaData domain objects for the user from the AppMetaDataDAO
	 * @return	String - returns next application id in the sequence
	 */	
	public String getNextApplicationId() {
		return this.appMetaDataDAO.getNextApplicationId();
	}
	/**
	 * Description:
	 * findAppMetaDataByUserId:	Method to get find all the Application requests user ID
	 * This method acquires the AppMetaData domain objects for the user from the AppMetaDataDAO
	 * @param	userId Long	Unique User ID
	 * @return	- List<AppMetaData> - returns a list of AppMetaData
	 */	
	public List<AppMetaData> findAppMetaDataByUserId(Long id) {
		return this.appMetaDataDAO.findAppMetaDataByUserId(id);
	}
	/**
	 * Description:
	 * findByClientRefNo:	Method to get find all the Application requests by Client Ref Number
	 * This method acquires the AppMetaData domain objects from the AppMetaDataDAO
	 * @param	refNo String
	 * @return	- List<AppMetaData> - returns a list of AppMetaData
	 */
	public AppMetaData findByClientRefNo(String refNo) {
		return this.appMetaDataDAO.findByClientRefNo(refNo);
	}
	/**
	 * Description:
	 * findCompletedAppMetaDataByUserId: Method to find the completed application requests of a user
	 * This method acquires the AppMetaData domain objects for the user from the AppMetaDataDAO
	 * @param	userId Long	Unique User ID
	 * @return	- List<AppMetaData> - returns a list of AppMetaData
	 */
	public List<AppMetaData> findCompletedAppMetaDataByUserId(Long id) throws LookupException {
		return this.appMetaDataDAO.findCompletedAppMetaDataByUserId(id);
	}
	/**
	 * Description:
	 * isValidClient: Method to find the whether client is valid
	 * This method acquires the AppMetaData domain object from the AppMetaDataDAO
	 * @author Dicetek.Ismail
	 * @param	applicationId Long	Unique application ID
	 * @return	boolean - returns true if the application is rejected, else returns false
	 */
	@Transactional(readOnly=true)
	public boolean isValidClient(Long applicationId) {
		AppMetaData appMetaData = this.appMetaDataDAO.findByPrimaryKey(applicationId.toString());
		if(appMetaData != null && appMetaData.getWfStatus().equals(ConstantsCommon.REJECT) ){
			return true;
		}
		return false;
	}
	/**
	 * Description:
	 * updateStatus: Method to update the status of the application request
	 * @author Dicetek.Ismail
	 * @param	applicationId Long	Unique application ID
	 * @param	statusEn String
	 * @param	statusAr String
	 * @return	-
	 */
	@Transactional(readOnly=false)
	public void updateStatus(String applicationId, String statusEn,String statusAr) {
		this.appMetaDataDAO.updateStatus(applicationId, statusEn, statusAr);
	}
	/**
	 * Description:
	 * findApplicationRequestsByProcessCode:	Method to get all the Application requests belonging to a process
	 * This method acquires the AppMetaData domain objects belonging to the process from the underlying AppMetaDataDAO 
	 * @author Dicetek.Ismail
	 * @param	processType WFProcessType
	 * @return	- List<AppMetaData> - returns a list of AppMetaData
	 */	
	@Transactional(readOnly=true)
	public List<AppMetaData> findApplicationRequestsByProcessCode(WFProcessType processType) {
		AppMetaDataDetailVO appMetaDataDetailVO = new AppMetaDataDetailVO();
		appMetaDataDetailVO.setProcessCode(processType);
		return this.appMetaDataDAO.findAppMetaDataByExample(appMetaDataDetailVO);

	}
	/**
	 * Description:
	 * findApplicationRequestsByInitiator:	Method to get all the Application requests belonging to a user
	 * This method acquires the AppMetaData domain objects belonging to the user from the underlying AppMetaDataDAO 
	 * @author Dicetek.Ismail
	 * @param	username String
	 * @return	- List<AppMetaData> - returns a list of AppMetaData
	 */	
	@Transactional(readOnly=true)
	public List<AppMetaData> findApplicationRequestsByInitiator(String username) {
		AppMetaDataDetailVO appMetaDataDetailVO = new AppMetaDataDetailVO();
		appMetaDataDetailVO.setStrWFinitatedBy(username);
		return this.appMetaDataDAO.findAppMetaDataByExample(appMetaDataDetailVO);

	}
	/**
	 * Description:
	 * findApplicationRequestsByApplicationDate:	Method to get all the Application requests raised on a specified date
	 * This method acquires the AppMetaData domain objects from the underlying AppMetaDataDAO 
	 * @author Dicetek.Ismail
	 * @param	date String
	 * @return	- List<AppMetaData> - returns a list of AppMetaData
	 */	
	@Transactional(readOnly=true)
	public List<AppMetaData> findApplicationRequestsByApplicationDate(String date) {
		//return this.appMetaDataDAO.findApplicationRequestsByApplicationDate(date);
		AppMetaDataDetailVO appMetaDataDetailVO = new AppMetaDataDetailVO();
		appMetaDataDetailVO.setApplicationDate(date);
		return this.appMetaDataDAO.findAppMetaDataByExample(appMetaDataDetailVO);

	}
	/**
	 * Description:
	 * findAppMetaDataByExample:	Method to get all the Application requests by an example VO
	 * This method acquires the AppMetaData domain objects for the user from the underlying AppMetaDataDAO 
	 * @author Dicetek.Ismail
	 * @param	appMetaDataDetailVO AppMetaDataDetailVO	  Example VO with fields filled for filtering the results
	 * @return	- List<AppMetaData> - returns a list of AppMetaData
	 */	
	public List<AppMetaData> findAppMetaDataByExample(AppMetaDataDetailVO appMetaDataDetailVO) {
		return this.appMetaDataDAO.findAppMetaDataByExample(appMetaDataDetailVO);
	}
	/**
	 * Description:
	 * findAppMetaDataByUserName:	Method to get all the Application requests raised by the user
	 * This method gets the objects from the underlying AppMetaDataDAO
	 * @author Dicetek.Ismail
	 * @param	strUserName String
	 * @return	- List<AppMetaData> - returns a list of AppMetaData
	 */	
	public List<AppMetaData> findAppMetaDataByUserName(String strUserName) {
		return this.appMetaDataDAO.findAppMetaDataByUserName(strUserName);
	}

	public List<WorkflowRequestVO> findWorkflowRequests(WorkflowRequestSearchCriteriaVO searchCriteria) {
		return this.appMetaDataDAO.findWorkflowRequests(searchCriteria);
	}

//	public List<AppMetaData> findCompletedAppMetaDataByUserId(AppMetaDataDetailVO appMetaDataDetailVO) {
//		// TODO Auto-generated method stub
//		return this.appMetaDataDAO.findCompletedAppMetaDataByUserId(appMetaDataDetailVO);
//	}
	
	
	/**
	 * updateAppMetaDataWithActionTaken
	 * 
	 * @see ae.pcfc.etks.online.common.domain.manager.AppMetaDataDomainObjectManager#updateAppMetaDataWithActionTaken(ae.pcfc.etks.online.common.domain.AppMetaData, java.lang.String)
	 * 
	 */
	public void updateAppMetaDataWithActionTaken(AppMetaData appMetaData, String strStepName) {
		ProcessStep processStep = null;
		if(appMetaData.getProcess() != null && appMetaData.getProcess().getProcessSteps() != null){
			for(ProcessStep ps : appMetaData.getProcess().getProcessSteps()){
				if(ps.getProcessStepCode().equals(strStepName)){
					processStep = ps;
					break;
				}
			}
		}
		for (ProcStepsComnts stepsComnts : appMetaData.getProcStepsComntses()) {
			stepsComnts.setAppMetaData(appMetaData);
			if(stepsComnts.getProcessStep() == null){
				stepsComnts.setProcessStep(processStep);
			}
		}
		for (ProcStepActions stepActions : appMetaData.getProcStepActionses()) {
			stepActions.setAppMetaData(appMetaData);
			if(stepActions.getProcessStep() == null){
				stepActions.setProcessStep(processStep);
			}
		}
	}

	/* (non-Javadoc)
	 * @see ae.pcfc.etks.online.common.domain.manager.AppMetaDataDomainObjectManager#undoUpdateAppMetaDataWithActionTaken(ae.pcfc.etks.online.common.domain.AppMetaData, java.lang.String)
	 */
	public void undoUpdateAppMetaDataWithActionTaken(AppMetaData appMetaData, String strStepName) {
		List<ProcStepsComnts> stepsComntsList = new ArrayList<ProcStepsComnts>();
		stepsComntsList.addAll(appMetaData.getProcStepsComntses());
		for (ProcStepsComnts stepsComnts : stepsComntsList) {
			if(stepsComnts.getProcessStep() == null || stepsComnts.getProcessStep().getProcessStepCode().equalsIgnoreCase(strStepName)){
				appMetaData.getProcStepsComntses().remove(stepsComnts);
			}
		}
		List<ProcStepActions> stepActionsList = new ArrayList<ProcStepActions>();
		stepActionsList.addAll(appMetaData.getProcStepActionses());
		for (ProcStepActions stepActions : stepActionsList ) {
			if(stepActions.getProcessStep() == null || stepActions.getProcessStep().getProcessStepCode().equalsIgnoreCase(strStepName)){
				appMetaData.getProcStepActionses().remove(stepActions);
			}
		}
	}

	/**
	 * validateAppMetaDataWithStep
	 * 
	 * @see ae.pcfc.etks.online.common.domain.manager.AppMetaDataDomainObjectManager#validateAppMetaDataWithStep(ae.pcfc.etks.online.common.domain.AppMetaData, java.lang.String)
	 * 
	 */
	public boolean validateAppMetaDataWithStep(AppMetaData appMetaData, String strStepName) {
	    boolean isStepAlreadyExist = false;
	    if(appMetaData != null){
		if(appMetaData.getProcStepsComntses() != null){
		    for (ProcStepsComnts stepsComnts : appMetaData.getProcStepsComntses()) {
			if(stepsComnts.getProcessStep()!= null && strStepName.equalsIgnoreCase(stepsComnts.getProcessStep().getProcessStepCode())){
			    isStepAlreadyExist = true;
			    break;
			}
		    }
		}
		if(appMetaData.getProcStepActionses() != null){
		    for (ProcStepActions stepActions : appMetaData.getProcStepActionses()) {
			if(stepActions.getProcessStep()!= null && strStepName.equalsIgnoreCase(stepActions.getProcessStep().getProcessStepCode())){
			    isStepAlreadyExist = true;
			    break;
			}
		    }
		}
	    }
	    return isStepAlreadyExist;
	}

	public List<LabelVO> searchRequestStatus(String searchString) {
		return this.appMetaDataDAO.searchRequestStatus(searchString);
	}
}
